package com.ziiwee.reduce.describe.creators.controllers;

import com.ziiwee.reduce.describe.DescribeException;
import com.ziiwee.reduce.describe.HandlerDescribe;
import com.ziiwee.reduce.describe.ResourceMethod;
import com.ziiwee.reduce.describe.creators.handlers.*;
import com.ziiwee.reduce.describe.utils.DescribeUtil;
import com.ziiwee.reduce.rest.ResourceService;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Page;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author ziiwee
 * @data 2020/8/12
 */
public class ResourceServiceControllerDescribeCreator extends AbstractControllerDescribeCreator {

    private final ResourceService<?, ?> service;
    private final ResolvableType type;
    private final ResolvableType subjectType;
    private final ResolvableType idType;

    public ResourceServiceControllerDescribeCreator(ResourceService<?, ?> service) {
        this.service = service;
        this.type = ResolvableType.forInstance(service);
        List<ResolvableType> args = DescribeUtil.getTypeArgsByResolvableType(type, ResourceService.class);
        if (args.size() != 2) {
            throw new DescribeException("错误的 RestfulService ,无法获取泛型参数:" + type);
        }
        subjectType = args.get(0);
        idType = args.get(1);
    }

    @Override
    public AnnotatedElement getElement() {
        return service.getClass();
    }

    @Override
    public ResolvableType getDefaultType() {
        return type;
    }

    @Override
    public List<HandlerDescribe> getHandlers() {
        return DescribeUtil.createHandlers(null,service,subjectType,idType);
    }

    @Override
    public ResolvableType getSubjectType() {
        List<ResolvableType> args = DescribeUtil.getTypeArgsByResolvableType(type, ResourceService.class);
        if (args.size() != 2 || args.get(0).resolve() == null) {
            throw new DescribeException("不符合要求的 Controller ，该 Controller 无法获取泛型参数 ：" + DescribeUtil.getSimpleNameByResolvableType(type));
        }
        return args.get(0);
    }

}
